import React, { memo, useCallback, useRef, useState } from 'react';
import { shallowEqual, useDispatch, useSelector } from 'react-redux';
import { CSSTransition } from 'react-transition-group';
import {
  changeCurrentIndexAction,
  changeCurrentSongAction,
  changePlayingStateAction,
  changePlayListAction,
  changePlayModeAction,
  changeSequecePlayListAction,
  changeShowPlayListAction,
  deleteSongAction,
} from '../store/actionCreators';
import {
  ListContent,
  ListHeader,
  PlayListWrapper,
  ScrollWrapper,
} from './style';
import { getName, prefixStyle, shuffle, findIndex } from '@/api/utils';
import Scroll from '@/baseUI/scroll';
import { playMode } from '@/api/config';
import Confirm from '@/baseUI/confirm';
export default memo(function PlayList(props) {
  const {
    showPlayList,
    currentIndex,
    currentSong,
    mode, //播放模式
    sequencePlayList, //顺序列表
    playList,
  } = useSelector(
    (state) => ({
      showPlayList: state.player.showPlayList,
      fullScreen: state.player.fullScreen,
      playing: state.player.playing,
      currentSong: state.player.currentSong,
      mode: state.player.mode,
      currentIndex: state.player.currentIndex,
      sequencePlayList: state.player.sequencePlayList,
      playList: state.player.playList,
    }),
    shallowEqual
  );

  const dispatch = useDispatch();

  const playListRef = useRef();
  const listWrapperRef = useRef();
  const [isShow, setIsShow] = useState(false);
  const transform = prefixStyle('transform');
  const confirmRef = useRef();
  // 是否允许滑动事件生效
  const [canTouch, setCanTouch] = useState(true);
  //touchStart 后记录 y 值
  const [startY, setStartY] = useState(0);
  //touchStart 事件是否已经被触发
  const [initialed, setInitialed] = useState(0);
  // 用户下滑的距离
  const [distance, setDistance] = useState(0);
  const listContentRef = useRef();
  const togglePlayListDispatch = (data) => {
    dispatch(changeShowPlayListAction(data));
  };
  // 修改当前歌曲在列表中的 index，也就是切歌
  const changeCurrentIndexDispatch = (data) => {
    dispatch(changeCurrentIndexAction(data));
  };
  // 修改当前的播放模式
  const changeModeDispatch = (data) => {
    dispatch(changePlayModeAction(data));
  };
  // 修改当前的歌曲列表
  const changePlayListDispatch = (data) => {
    dispatch(changePlayListAction(data));
  };
  const deleteSongDispatch = (data) => {
    dispatch(deleteSongAction(data));
  };
  const clearDispatch = () => {
    // 1. 清空两个列表
    dispatch(changePlayListAction([]));
    dispatch(changeSequecePlayListAction([]));
    // 2. 初始 currentIndex
    dispatch(changeCurrentIndexAction(-1));
    // 3. 关闭 PlayList 的显示
    dispatch(changeShowPlayListAction(false));
    // 4. 将当前歌曲置空
    dispatch(changeCurrentSongAction({}));
    // 5. 重置播放状态
    dispatch(changePlayingStateAction(false));
  };
  const getCurrentIcon = (item) => {
    // 是不是当前正在播放的歌曲
    const current = currentSong.id === item.id;
    const className = current ? 'icon-play' : '';
    const content = current ? '&#xe6e3;' : '';
    return (
      <i
        className={`current iconfont ${className}`}
        dangerouslySetInnerHTML={{ __html: content }}
      ></i>
    );
  };
  const getPlayMode = () => {
    let content, text;
    if (mode === playMode.sequence) {
      content = '&#xe625;';
      text = '顺序播放';
    } else if (mode === playMode.loop) {
      content = '&#xe653;';
      text = '单曲循环';
    } else {
      content = '&#xe61b;';
      text = '随机播放';
    }
    return (
      <div>
        <i
          className="iconfont"
          onClick={(e) => changeMode(e)}
          dangerouslySetInnerHTML={{ __html: content }}
        ></i>
        <span className="text" onClick={(e) => changeMode(e)}>
          {text}
        </span>
      </div>
    );
  };
  const changeMode = (e) => {
    let newMode = (mode + 1) % 3;
    if (newMode === 0) {
      // 顺序模式
      changePlayListDispatch(sequencePlayList);
      let index = findIndex(currentSong, sequencePlayList);
      changeCurrentIndexDispatch(index);
    } else if (newMode === 1) {
      // 单曲循环
      changePlayListDispatch(sequencePlayList);
    } else if (newMode === 2) {
      // 随机播放
      let newList = shuffle(sequencePlayList);
      let index = findIndex(currentSong, newList);
      changePlayListDispatch(newList);
      changeCurrentIndexDispatch(index);
    }
    changeModeDispatch(newMode);
  };
  const onEnterCB = useCallback(() => {
    // 让列表显示
    setIsShow(true);
    // 最开始是隐藏在下面
    listWrapperRef.current.style[transform] = `translate3d(0, 100%, 0)`;
  }, [transform]);

  const onEnteringCB = useCallback(() => {
    // 让列表展现
    listWrapperRef.current.style['transition'] = 'all 0.3s';
    listWrapperRef.current.style[transform] = `translate3d(0, 0, 0)`;
  }, [transform]);
  const onExitingCB = useCallback(() => {
    listWrapperRef.current.style['transition'] = 'all 0.3s';
    listWrapperRef.current.style[transform] = `translate3d(0px, 100%, 0px)`;
  }, [transform]);
  const onExitedCB = useCallback(() => {
    setIsShow(false);
    listWrapperRef.current.style[transform] = `translate3d(0px, 100%, 0px)`;
  }, [transform]);
  const handleChangeCurrentIndex = (index) => {
    if (currentIndex === index) return;
    changeCurrentIndexDispatch(index);
  };

  const handleDeleteSong = (e, song) => {
    e.stopPropagation();
    deleteSongDispatch(song);
  };
  const handleShowClear = () => {
    confirmRef.current.show();
  };
  const handleConfirmClear = () => {
    clearDispatch();
  };
  const handleTouchStart = (e) => {
    setDistance(0)
    if (!canTouch || initialed) return;
    listWrapperRef.current.style['transition'] = '';
    setStartY(e.nativeEvent.touches[0].pageY); // 记录 y 值
    setInitialed(true);
  };
  const handleTouchMove = (e) => {
    if (!canTouch || !initialed) return;
    let distance = e.nativeEvent.touches[0].pageY - startY;
    if (distance < 0) return;
    setDistance(distance); // 记录下滑距离
    listWrapperRef.current.style.transform = `translate3d(0, ${distance} px, 0)`;
  };
  const handleTouchEnd = (e) => {
    setInitialed(false);
    // 这里设置阈值为 150px
    if (distance >= 150) {
      // 大于 150px 则关闭 PlayList
      togglePlayListDispatch(false);
    } else {
      // 否则反弹回去
      listWrapperRef.current.style['transition'] = 'all 0.3s';
      listWrapperRef.current.style[transform] = `translate3d(0px, 0px, 0px)`;
    }
  };
  const handleScroll = (pos) => {
    // 只有当内容偏移量为 0 的时候才能下滑关闭 PlayList。否则一边内容在移动，一边列表在移动，出现 bug
    let state = pos.y === 0;
    setCanTouch(state);
  };
  return (
    <CSSTransition
      in={showPlayList} // 控制动画
      timeout={300}
      classNames="list-fade"
      onEnter={onEnterCB}
      onEntering={onEnteringCB}
      onExiting={onExitingCB}
      onExited={onExitedCB}
    >
      <PlayListWrapper
        ref={playListRef}
        style={isShow === true ? { display: 'block' } : { display: 'none' }} //控制列表显示与否
        onClick={() => togglePlayListDispatch(false)}
      >
        <div
          className="list_wrapper"
          ref={listWrapperRef}
          onClick={(e) => e.stopPropagation()}
          onTouchStart={handleTouchStart}
          onTouchMove={handleTouchMove}
          onTouchEnd={handleTouchEnd}
        >
          <ListHeader>
            <h1 className="title">
              {getPlayMode()}
              <span className="iconfont clear" onClick={handleShowClear}>
                &#xe63d;
              </span>
            </h1>
          </ListHeader>
          <ScrollWrapper>
            <Scroll
              ref={listContentRef}
              onScroll={(pos) => handleScroll(pos)}
              bounceTop={false}
            >
              <ListContent>
                {playList.map((item, index) => {
                  return (
                    <li
                      className="item"
                      key={item.id}
                      onClick={() => handleChangeCurrentIndex(index)}
                    >
                      {getCurrentIcon(item)}
                      <span className="text">
                        {item.name} - {getName(item.ar)}
                      </span>
                      <span className="like">
                        <i className="iconfont">&#xe601;</i>
                      </span>
                      <span
                        className="delete"
                        onClick={(e) => handleDeleteSong(e, item)}
                      >
                        <i className="iconfont">&#xe63d;</i>
                      </span>
                    </li>
                  );
                })}
              </ListContent>
            </Scroll>
          </ScrollWrapper>
        </div>
        <Confirm
          ref={confirmRef}
          text={'是否删除全部？'}
          cancelBtnText={'取消'}
          confirmBtnText={'确定'}
          handleConfirm={handleConfirmClear}
        />
      </PlayListWrapper>
    </CSSTransition>
  );
});
